package pl.edu.pw.MidEmu.UI.Components;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Point;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;

import pl.edu.pw.MidEmu.Base.Components.BaseFrame;
import pl.edu.pw.MidEmu.Common.Consts;
import pl.edu.pw.MidEmu.Common.Models.CBRDModel;
import pl.edu.pw.MidEmu.Common.Models.ClassSettingsModel;
import pl.edu.pw.MidEmu.Common.Models.MidasModel;
import pl.edu.pw.MidEmu.UI.Controllers.RunningApplicationsListController;
import pl.edu.pw.MidEmu.UI.Views.RunningApplicationsListView;

/**
 * Frame with GUI for managing running applications
 * @author Mateusz Starodab
 *
 */
public class RunningApplicationsListFrame extends BaseFrame<JFrame, RunningApplicationsListController> implements RunningApplicationsListView
{
	private JButton btnClose;
	private JButton btnNew;

	private JList lstCenterApps;
	private DefaultListModel lstCenterModel;
	private JList lstNorthApps;

	private DefaultListModel lstNorthModel;
	private JMenuItem miShowOutput;
	private JMenuItem miShowSettings;

	private MidasComponent parent;
	private JPopupMenu pmContext;
	private JPanel pnlCenter;

	private JPanel pnlContent;
	private JPanel pnlNorth;
	private JPanel pnlOuterContent;

	private JPanel pnlSouth;

	public RunningApplicationsListFrame(MidasComponent component)
	{
		RunningApplicationsListController controller = new RunningApplicationsListController(component.getApplications());
		controller.setView(this);
		setController(controller);
		JFrame frame = new JFrame();
		setComponent(frame);

		parent = component;

		getComponent().setTitle(Consts.MainFrame_Title + " - " + parent.getName() + " - " + Consts.RunnungApplicationList_Title);
		getComponent().setSize(300, 320);
		getComponent().setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

		pnlContent = new JPanel();
		pnlContent.setLayout(new BoxLayout(pnlContent, BoxLayout.Y_AXIS));

		pnlOuterContent = new JPanel();
		pnlOuterContent.setLayout(new BorderLayout());

		pnlNorth = new JPanel();
		pnlNorth.setLayout(new BorderLayout());
		pnlNorth.setBorder(BorderFactory.createTitledBorder(Consts.RunnungApplicationList_ActiveLabel));

		lstNorthModel = new DefaultListModel();
		for (ClassSettingsModel model : getController().getActiveApplicationModels())
			lstNorthModel.addElement(model);
		lstNorthApps = new JList(lstNorthModel);
		lstNorthApps.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		lstNorthApps.addMouseListener(getController());

		pnlNorth.add(lstNorthApps, BorderLayout.CENTER);

		pnlContent.add(pnlNorth);

		pnlCenter = new JPanel();
		pnlCenter.setLayout(new BorderLayout());
		pnlCenter.setBorder(BorderFactory.createTitledBorder(Consts.RunnungApplicationList_InactiveLabel));

		lstCenterModel = new DefaultListModel();
		for (ClassSettingsModel model : getController().getInactiveApplicationModels())
			lstCenterModel.addElement(model);
		lstCenterApps = new JList(lstCenterModel);
		lstCenterApps.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		lstCenterApps.addMouseListener(getController());

		pnlCenter.add(lstCenterApps, BorderLayout.CENTER);

		pnlContent.add(pnlCenter);

		pnlSouth = new JPanel();
		pnlSouth.setLayout(new FlowLayout(FlowLayout.CENTER));

		btnClose = new JButton(Consts.RunnungApplicationList_CloseButton);
		btnClose.setName(Consts.RunnungApplicationList_CloseButton);
		btnClose.addActionListener(getController());

		btnNew = new JButton(Consts.RunnungApplicationList_RunButton);
		btnNew.setName(Consts.RunnungApplicationList_RunButton);
		btnNew.addActionListener(getController());

		pnlSouth.add(btnNew);
		pnlSouth.add(btnClose);

		pnlOuterContent.add(pnlContent, BorderLayout.CENTER);
		pnlOuterContent.add(pnlSouth, BorderLayout.SOUTH);

		pmContext = new JPopupMenu();
		miShowSettings = new JMenuItem(Consts.RunnungApplicationList_ShowSettings);
		miShowSettings.setName(Consts.RunnungApplicationList_ShowSettings);
		miShowSettings.addActionListener(getController());
		miShowOutput = new JMenuItem(Consts.RunnungApplicationList_ShowOutput);
		miShowOutput.setName(Consts.RunnungApplicationList_ShowOutput);
		miShowOutput.addActionListener(getController());

		pmContext.add(miShowOutput);
		pmContext.add(miShowSettings);

		getComponent().setContentPane(pnlOuterContent);
	}

	@Override
	public void close()
	{
		getComponent().setVisible(false);
		getComponent().dispose();
	}

	/**
	 * @return
	 * @uml.property  name="parent"
	 */
	@Override
	public MidasComponent getParent()
	{
		return parent;
	}

	@Override
	public void rebindModels()
	{
		lstNorthModel.clear();
		for (ClassSettingsModel model : getController().getActiveApplicationModels())
			lstNorthModel.addElement(model);

		lstCenterModel.clear();
		for (ClassSettingsModel model : getController().getInactiveApplicationModels())
			lstCenterModel.addElement(model);

		getComponent().invalidate();
	}

	@Override
	public void showClasLoadingFrame(Point point)
	{
		ApplicationsListFrame list = new ApplicationsListFrame(parent);
		list.getComponent().setLocation(point);
		list.getComponent().setVisible(true);
		rebindModels();
	}

	@Override
	public void showOutputWindow(ClassSettingsModel selectedModel, Point point)
	{
		ApplicationOutputsFrame frame = new ApplicationOutputsFrame(parent);
		if (!(selectedModel instanceof MidasModel) && !(selectedModel instanceof CBRDModel))
			frame.setVisibleTab(selectedModel.get_className());
		frame.getComponent().setLocation(point);
		frame.getComponent().setVisible(true);
	}

	@Override
	public void showPopupMenu(Component component, int x, int y, boolean isInside)
	{
		pmContext.show(component, x, y);
	}

	@Override
	public void showSettingsWindow(ClassSettingsModel selectedModel, Point point)
	{
		GenericDataDisplayer dd = new GenericDataDisplayer(parent, Consts.RunnungApplicationList_AplicationData, selectedModel.getClassData());
		dd.getComponent().setLocation(point);
		dd.getComponent().setVisible(true);
	}
}
